#pragma once
#include "nameble_object.h"
#include "aabb.h"
#include "vertex.h"
#include <string>
#include <list>

namespace krryn{
namespace view{
	class texture;
	class effect;
};

namespace scene{
	class mesh : public nameble_object{
	public:
		typedef std::list<view::effect*> effect_list_t;
		mesh() : m_Name("Anonymous mesh"), m_Texture(0), m_Scale(1) {}

		virtual const std::string &get_name() {return m_Name;}
		virtual void set_name(const std::string &a_Name) {m_Name = a_Name;}

		void set_vertex_count(size_t a_Count) {m_VertexCount = a_Count;}
		void set_vertices(vertex *a_Vertices) {m_Vertices = a_Vertices;}

		void set_index_count(size_t a_Count)  {m_IndexCount = a_Count;}
		void set_indices(size_t *a_Indices)   {m_Indices  = a_Indices;}

		size_t get_index_count() {return m_IndexCount;}
		size_t get_vertex_count() {return m_VertexCount;}

		vertex &get_vertex(size_t a_Position) {return m_Vertices[m_Indices[a_Position]];}

		void set_texture(view::texture *a_Texture) {m_Texture = a_Texture;}
		view::texture *get_texture() {return m_Texture;}

		void add_effect(view::effect *a_Effect) {m_Effects.push_back(a_Effect);}
		const effect_list_t &get_effects() {return m_Effects;}

		vertex *get_vertices() const{return m_Vertices;}
		size_t *get_indices() const{return m_Indices;}

		float get_scale() const{return m_Scale;}
		void set_scale(float a_Scale){m_Scale = a_Scale;}

		void update_normals();
		void make_counter_clockwise();
		void update_aabb();

		math::aabb get_aabb() const{return m_Aabb;}

	private:
		view::texture *m_Texture;
		size_t m_VertexCount, m_IndexCount;
		size_t *m_Indices;
		vertex *m_Vertices;
		std::string m_Name;
		math::aabb m_Aabb;
		float m_Scale;
		effect_list_t m_Effects;
	};
}
}
